-2001-03-29 Alexander Larsson <alexl@redhat.com>
+Wed Mar 28 00:03:10 2001 Owen Taylor <otaylor@redhat.com>
+
+ [ Patch from Havoc Pennington, hp@redhat.com ]
+
+ * gdk/gdkwindow.h gdk/x11/gdkwindow-x11.c:
+ Add functions gdk_window_begin_resize_drag/begin_move_drag
+ to start resizing or moving a toplevel window. This
+ is done either using the _NET_WM_MOVERESIZE protocol,
+ or, if that isn't present, by emulation.
+
+ * gtk/gtkwindow.[ch]: Add functions gtk_begin_move/resize_drag
+ to export the above to GTK+-land.
+
+ * gtk/gtkstyle.[ch]: Add ->draw_resize_grip() paint func.
+
+ * gtk/gtkwindow.c gdk/gdkwindow.[ch] (gdk_window_constrain_size):
+ Move this function into gdkwindow, since we need it
+ when implementing fallback resizing.
+
+ * gdk/x11/gdkwindow-x11.c: gdk_window_set_geometry_hints.
+ Fix typo when setting gravity.
+
+ * gtk/gtkstatusbar.[ch] (gtk_statusbar_set_has_resize_grip):
+ Add an optional (but on by default) resize grip for resizing
+ the parent window.
+
+01-03-29 Alexander Larsson <alexl@redhat.com>
* gtk/gtktooltips.c (gtk_tooltips_event_handler):
Don't return TRUE from the event handler, that blocks all
-2001-03-29 Alexander Larsson <alexl@redhat.com>
+Wed Mar 28 00:03:10 2001 Owen Taylor <otaylor@redhat.com>
+
+ [ Patch from Havoc Pennington, hp@redhat.com ]
+
+ * gdk/gdkwindow.h gdk/x11/gdkwindow-x11.c:
+ Add functions gdk_window_begin_resize_drag/begin_move_drag
+ to start resizing or moving a toplevel window. This
+ is done either using the _NET_WM_MOVERESIZE protocol,
+ or, if that isn't present, by emulation.
+
+ * gtk/gtkwindow.[ch]: Add functions gtk_begin_move/resize_drag
+ to export the above to GTK+-land.
+
+ * gtk/gtkstyle.[ch]: Add ->draw_resize_grip() paint func.
+
+ * gtk/gtkwindow.c gdk/gdkwindow.[ch] (gdk_window_constrain_size):
+ Move this function into gdkwindow, since we need it
+ when implementing fallback resizing.
+
+ * gdk/x11/gdkwindow-x11.c: gdk_window_set_geometry_hints.
+ Fix typo when setting gravity.
+
+ * gtk/gtkstatusbar.[ch] (gtk_statusbar_set_has_resize_grip):
+ Add an optional (but on by default) resize grip for resizing
+ the parent window.
+
+01-03-29 Alexander Larsson <alexl@redhat.com>
* gtk/gtktooltips.c (gtk_tooltips_event_handler):
Don't return TRUE from the event handler, that blocks all
-2001-03-29 Alexander Larsson <alexl@redhat.com>
+Wed Mar 28 00:03:10 2001 Owen Taylor <otaylor@redhat.com>
+
+ [ Patch from Havoc Pennington, hp@redhat.com ]
+
+ * gdk/gdkwindow.h gdk/x11/gdkwindow-x11.c:
+ Add functions gdk_window_begin_resize_drag/begin_move_drag
+ to start resizing or moving a toplevel window. This
+ is done either using the _NET_WM_MOVERESIZE protocol,
+ or, if that isn't present, by emulation.
+
+ * gtk/gtkwindow.[ch]: Add functions gtk_begin_move/resize_drag
+ to export the above to GTK+-land.
+
+ * gtk/gtkstyle.[ch]: Add ->draw_resize_grip() paint func.
+
+ * gtk/gtkwindow.c gdk/gdkwindow.[ch] (gdk_window_constrain_size):
+ Move this function into gdkwindow, since we need it
+ when implementing fallback resizing.
+
+ * gdk/x11/gdkwindow-x11.c: gdk_window_set_geometry_hints.
+ Fix typo when setting gravity.
+
+ * gtk/gtkstatusbar.[ch] (gtk_statusbar_set_has_resize_grip):
+ Add an optional (but on by default) resize grip for resizing
+ the parent window.
+
+01-03-29 Alexander Larsson <alexl@redhat.com>
* gtk/gtktooltips.c (gtk_tooltips_event_handler):
Don't return TRUE from the event handler, that blocks all
-2001-03-29 Alexander Larsson <alexl@redhat.com>
+Wed Mar 28 00:03:10 2001 Owen Taylor <otaylor@redhat.com>
+
+ [ Patch from Havoc Pennington, hp@redhat.com ]
+
+ * gdk/gdkwindow.h gdk/x11/gdkwindow-x11.c:
+ Add functions gdk_window_begin_resize_drag/begin_move_drag
+ to start resizing or moving a toplevel window. This
+ is done either using the _NET_WM_MOVERESIZE protocol,
+ or, if that isn't present, by emulation.
+
+ * gtk/gtkwindow.[ch]: Add functions gtk_begin_move/resize_drag
+ to export the above to GTK+-land.
+
+ * gtk/gtkstyle.[ch]: Add ->draw_resize_grip() paint func.
+
+ * gtk/gtkwindow.c gdk/gdkwindow.[ch] (gdk_window_constrain_size):
+ Move this function into gdkwindow, since we need it
+ when implementing fallback resizing.
+
+ * gdk/x11/gdkwindow-x11.c: gdk_window_set_geometry_hints.
+ Fix typo when setting gravity.
+
+ * gtk/gtkstatusbar.[ch] (gtk_statusbar_set_has_resize_grip):
+ Add an optional (but on by default) resize grip for resizing
+ the parent window.
+
+01-03-29 Alexander Larsson <alexl@redhat.com>
* gtk/gtktooltips.c (gtk_tooltips_event_handler):
Don't return TRUE from the event handler, that blocks all
-2001-03-29 Alexander Larsson <alexl@redhat.com>
+Wed Mar 28 00:03:10 2001 Owen Taylor <otaylor@redhat.com>
+
+ [ Patch from Havoc Pennington, hp@redhat.com ]
+
+ * gdk/gdkwindow.h gdk/x11/gdkwindow-x11.c:
+ Add functions gdk_window_begin_resize_drag/begin_move_drag
+ to start resizing or moving a toplevel window. This
+ is done either using the _NET_WM_MOVERESIZE protocol,
+ or, if that isn't present, by emulation.
+
+ * gtk/gtkwindow.[ch]: Add functions gtk_begin_move/resize_drag
+ to export the above to GTK+-land.
+
+ * gtk/gtkstyle.[ch]: Add ->draw_resize_grip() paint func.
+
+ * gtk/gtkwindow.c gdk/gdkwindow.[ch] (gdk_window_constrain_size):
+ Move this function into gdkwindow, since we need it
+ when implementing fallback resizing.
+
+ * gdk/x11/gdkwindow-x11.c: gdk_window_set_geometry_hints.
+ Fix typo when setting gravity.
+
+ * gtk/gtkstatusbar.[ch] (gtk_statusbar_set_has_resize_grip):
+ Add an optional (but on by default) resize grip for resizing
+ the parent window.
+
+01-03-29 Alexander Larsson <alexl@redhat.com>
* gtk/gtktooltips.c (gtk_tooltips_event_handler):
Don't return TRUE from the event handler, that blocks all
-2001-03-29 Alexander Larsson <alexl@redhat.com>
+Wed Mar 28 00:03:10 2001 Owen Taylor <otaylor@redhat.com>
+
+ [ Patch from Havoc Pennington, hp@redhat.com ]
+
+ * gdk/gdkwindow.h gdk/x11/gdkwindow-x11.c:
+ Add functions gdk_window_begin_resize_drag/begin_move_drag
+ to start resizing or moving a toplevel window. This
+ is done either using the _NET_WM_MOVERESIZE protocol,
+ or, if that isn't present, by emulation.
+
+ * gtk/gtkwindow.[ch]: Add functions gtk_begin_move/resize_drag
+ to export the above to GTK+-land.
+
+ * gtk/gtkstyle.[ch]: Add ->draw_resize_grip() paint func.
+
+ * gtk/gtkwindow.c gdk/gdkwindow.[ch] (gdk_window_constrain_size):
+ Move this function into gdkwindow, since we need it
+ when implementing fallback resizing.
+
+ * gdk/x11/gdkwindow-x11.c: gdk_window_set_geometry_hints.
+ Fix typo when setting gravity.
+
+ * gtk/gtkstatusbar.[ch] (gtk_statusbar_set_has_resize_grip):
+ Add an optional (but on by default) resize grip for resizing
+ the parent window.
+
+01-03-29 Alexander Larsson <alexl@redhat.com>
* gtk/gtktooltips.c (gtk_tooltips_event_handler):
Don't return TRUE from the event handler, that blocks all
-2001-03-29 Alexander Larsson <alexl@redhat.com>
+Wed Mar 28 00:03:10 2001 Owen Taylor <otaylor@redhat.com>
+
+ [ Patch from Havoc Pennington, hp@redhat.com ]
+
+ * gdk/gdkwindow.h gdk/x11/gdkwindow-x11.c:
+ Add functions gdk_window_begin_resize_drag/begin_move_drag
+ to start resizing or moving a toplevel window. This
+ is done either using the _NET_WM_MOVERESIZE protocol,
+ or, if that isn't present, by emulation.
+
+ * gtk/gtkwindow.[ch]: Add functions gtk_begin_move/resize_drag
+ to export the above to GTK+-land.
+
+ * gtk/gtkstyle.[ch]: Add ->draw_resize_grip() paint func.
+
+ * gtk/gtkwindow.c gdk/gdkwindow.[ch] (gdk_window_constrain_size):
+ Move this function into gdkwindow, since we need it
+ when implementing fallback resizing.
+
+ * gdk/x11/gdkwindow-x11.c: gdk_window_set_geometry_hints.
+ Fix typo when setting gravity.
+
+ * gtk/gtkstatusbar.[ch] (gtk_statusbar_set_has_resize_grip):
+ Add an optional (but on by default) resize grip for resizing
+ the parent window.
+
+01-03-29 Alexander Larsson <alexl@redhat.com>
* gtk/gtktooltips.c (gtk_tooltips_event_handler):
Don't return TRUE from the event handler, that blocks all
GdkWindowImplX11
GdkColormap
GtkSettings
+ GtkRcStyle
GdkPixbufLoader
GdkPixmap
GdkColormap
GtkSettings
+ GtkRcStyle
GtkObject
GtkWidget
GtkMisc
</para>
+<!-- ##### ARG GtkCheckMenuItem:inconsistent ##### -->
+<para>
+
+</para>
+
@entry: the object which received the signal.
+<!-- ##### SIGNAL GtkEntry::populate-popup ##### -->
+<para>
+
+</para>
+
+@entry: the object which received the signal.
+@arg1:
+
<!-- ##### SIGNAL GtkEntry::toggle-overwrite ##### -->
<para>
#GtkRcStyle structures to form a #GtkStyle.
</para>
-@parent_instance:
@name:
@bg_pixmap_name:
@font_desc:
the callbacks.
-<!-- ##### FUNCTION gtk_signal_lookup ##### -->
+<!-- ##### MACRO gtk_signal_lookup ##### -->
<para>
Given the name of the signal and the type of object it connects
to, get the signal's identifying integer. Emitting the signal
It also tries the ancestors of the given type.
</para>
+@Returns: the signal's identifying number, or 0 if no signal was found.
+<!-- # Unused Parameters # -->
@name: the signal's name, e.g. clicked.
@object_type: the type that the signal operates on, e.g. #GTK_TYPE_BUTTON.
-@Returns: the signal's identifying number, or 0 if no signal was found.
-<!-- ##### FUNCTION gtk_signal_name ##### -->
+<!-- ##### MACRO gtk_signal_name ##### -->
<para>
Given the signal's identifier, find its name.
</para>
Two different signals may have the same name, if they have differing types.
</para>
-@signal_id: the signal's identifying number.
@Returns: the signal name, or NULL if the signal number was invalid.
+<!-- # Unused Parameters # -->
+@signal_id: the signal's identifying number.
<!-- ##### FUNCTION gtk_signal_emit ##### -->
followed by one which is a pointer to the return type.
-<!-- ##### FUNCTION gtk_signal_emit_stop ##### -->
+<!-- ##### MACRO gtk_signal_emit_stop ##### -->
<para>
This function aborts a signal's current emission.
</para>
isn't being emitted.
</para>
-@object: the object whose signal handlers you wish to stop.
-@signal_id: the signal identifier, as returned by gtk_signal_lookup().
-<!-- # Unused Parameters # -->
@i:
@s:
+<!-- # Unused Parameters # -->
+@object: the object whose signal handlers you wish to stop.
+@signal_id: the signal identifier, as returned by gtk_signal_lookup().
<!-- ##### FUNCTION gtk_signal_emit_stop_by_name ##### -->
@name: the name of the signal you wish to stop.
-<!-- ##### FUNCTION gtk_signal_connect ##### -->
+<!-- ##### MACRO gtk_signal_connect ##### -->
<para>
Attach a function pointer and user data to a signal for
a particular object.
</programlisting>
</informalexample>
+@o:
+@s:
+@f:
+@d:
+@Returns: the connection id.
+<!-- # Unused Parameters # -->
@object: the object associated with the signal, e.g. if a button
is getting pressed, this is that button.
@name: name of the signal.
@func: function pointer to attach to the signal.
@func_data: value to pass as to your function (through the marshaller).
-@Returns: the connection id.
-<!-- # Unused Parameters # -->
-@o:
-@s:
-@f:
-@d:
-<!-- ##### FUNCTION gtk_signal_connect_after ##### -->
+<!-- ##### MACRO gtk_signal_connect_after ##### -->
<para>
Attach a function pointer and user data to a signal
so that this handler will be called after the other handlers.
</para>
-@object: the object associated with the signal.
-@name: name of the signal.
-@func: function pointer to attach to the signal.
-@func_data: value to pass as to your function (through the marshaller).
-@Returns: the unique identifier for this attachment: the connection id.
-<!-- # Unused Parameters # -->
@o:
@s:
@f:
@d:
+@Returns: the unique identifier for this attachment: the connection id.
+<!-- # Unused Parameters # -->
+@object: the object associated with the signal.
+@name: name of the signal.
+@func: function pointer to attach to the signal.
+@func_data: value to pass as to your function (through the marshaller).
-<!-- ##### FUNCTION gtk_signal_connect_object ##### -->
+<!-- ##### MACRO gtk_signal_connect_object ##### -->
<para>
This function is for registering a callback that will
call another object's callback. That is,
</programlisting>
</informalexample>
+@o:
+@s:
+@f:
+@d:
+@Returns: the connection id.
+<!-- # Unused Parameters # -->
@object: the object which emits the signal.
@name: the name of the signal.
@func: the function to callback.
@slot_object: the object to pass as the first parameter to func.
(Though it pretends to take an object, you can
really pass any gpointer as the #slot_object .)
-@Returns: the connection id.
-<!-- # Unused Parameters # -->
-@o:
-@s:
-@f:
-@d:
-<!-- ##### FUNCTION gtk_signal_connect_object_after ##### -->
+<!-- ##### MACRO gtk_signal_connect_object_after ##### -->
<para>
Attach a signal hook to a signal, passing in an alternate
object as the first parameter, and guaranteeing
handlers are called first.
</para>
-@object: the object associated with the signal.
-@name: name of the signal.
-@func: function pointer to attach to the signal.
-@slot_object: the object to pass as the first parameter to #func.
-@Returns: the connection id.
-<!-- # Unused Parameters # -->
@o:
@s:
@f:
@d:
+@Returns: the connection id.
+<!-- # Unused Parameters # -->
+@object: the object associated with the signal.
+@name: name of the signal.
+@func: function pointer to attach to the signal.
+@slot_object: the object to pass as the first parameter to #func.
<!-- ##### FUNCTION gtk_signal_connect_full ##### -->
@name: name of the signal.
-<!-- ##### FUNCTION gtk_signal_disconnect ##### -->
+<!-- ##### MACRO gtk_signal_disconnect ##### -->
<para>
Destroy a user-defined handler connection.
</para>
+<!-- # Unused Parameters # -->
@object: the object which the handler pertains to.
@handler_id: the connection id.
-<!-- ##### FUNCTION gtk_signal_disconnect_by_func ##### -->
+<!-- ##### MACRO gtk_signal_disconnect_by_func ##### -->
<para>
Destroy all connections for a particular object, with
the given function-pointer and user-data.
</para>
-@object: the object which emits the signal.
-@func: the function pointer to search for.
-@data: the user data to search for.
-<!-- # Unused Parameters # -->
@o:
@f:
@d:
+<!-- # Unused Parameters # -->
+@object: the object which emits the signal.
+@func: the function pointer to search for.
+@data: the user data to search for.
-<!-- ##### FUNCTION gtk_signal_disconnect_by_data ##### -->
+<!-- ##### MACRO gtk_signal_disconnect_by_data ##### -->
<para>
Destroy all connections for a particular object, with
the given user-data.
</para>
-@object: the object which emits the signal.
-@data: the user data to search for.
-<!-- # Unused Parameters # -->
@o:
@d:
+<!-- # Unused Parameters # -->
+@object: the object which emits the signal.
+@data: the user data to search for.
-<!-- ##### FUNCTION gtk_signal_handler_block ##### -->
+<!-- ##### MACRO gtk_signal_handler_block ##### -->
<para>
Prevent an user-defined handler from being invoked. All other
signal processing will go on as normal, but this particular
handler will ignore it.
</para>
+<!-- # Unused Parameters # -->
@object: the object which emits the signal to block.
@handler_id: the connection id.
-<!-- ##### FUNCTION gtk_signal_handler_block_by_func ##### -->
+<!-- ##### MACRO gtk_signal_handler_block_by_func ##### -->
<para>
Prevent a user-defined handler from being invoked, by reference to
the user-defined handler's function pointer and user data. (It may result in
multiple hooks being blocked, if you've called connect multiple times.)
</para>
-@object: the object which emits the signal to block.
-@func: the function pointer of the handler to block.
-@data: the user data of the handler to block.
-<!-- # Unused Parameters # -->
@o:
@f:
@d:
+<!-- # Unused Parameters # -->
+@object: the object which emits the signal to block.
+@func: the function pointer of the handler to block.
+@data: the user data of the handler to block.
-<!-- ##### FUNCTION gtk_signal_handler_block_by_data ##### -->
+<!-- ##### MACRO gtk_signal_handler_block_by_data ##### -->
<para>
Prevent all user-defined handlers with a certain user data from being invoked.
</para>
-@object: the object which emits the signal we want to block.
-@data: the user data of the handlers to block.
-<!-- # Unused Parameters # -->
@o:
@d:
+<!-- # Unused Parameters # -->
+@object: the object which emits the signal we want to block.
+@data: the user data of the handlers to block.
-<!-- ##### FUNCTION gtk_signal_handler_unblock ##### -->
+<!-- ##### MACRO gtk_signal_handler_unblock ##### -->
<para>
Undo a block, by connection id. Note that undoing a block doesn't
necessarily make the hook callable, because if you block a
hook twice, you must unblock it twice.
</para>
+<!-- # Unused Parameters # -->
@object: the object which emits the signal we want to unblock.
@handler_id: the emission handler identifier, as returned by
gtk_signal_connect(), etc.
-<!-- ##### FUNCTION gtk_signal_handler_unblock_by_func ##### -->
+<!-- ##### MACRO gtk_signal_handler_unblock_by_func ##### -->
<para>
Undo a block, by function pointer and data.
Note that undoing a block doesn't
hook twice, you must unblock it twice.
</para>
-@object: the object which emits the signal we want to unblock.
-@func: the function pointer to search for.
-@data: the user data to search for.
-<!-- # Unused Parameters # -->
@o:
@f:
@d:
+<!-- # Unused Parameters # -->
+@object: the object which emits the signal we want to unblock.
+@func: the function pointer to search for.
+@data: the user data to search for.
-<!-- ##### FUNCTION gtk_signal_handler_unblock_by_data ##### -->
+<!-- ##### MACRO gtk_signal_handler_unblock_by_data ##### -->
<para>
Undo block(s), to all signals for a particular object
with a particular user-data pointer
</para>
-@object: the object which emits the signal we want to unblock.
-@data: the user data to search for.
-<!-- # Unused Parameters # -->
@o:
@d:
+<!-- # Unused Parameters # -->
+@object: the object which emits the signal we want to unblock.
+@data: the user data to search for.
-<!-- ##### FUNCTION gtk_signal_handler_pending ##### -->
+<!-- ##### MACRO gtk_signal_handler_pending ##### -->
<para>
Returns a connection id corresponding to a given signal id and object.
</para>
thus saving the cost of building the arguments.
</para>
+@i:
+@s:
+@b:
+@Returns: the connection id, if a connection was found. 0 otherwise.
+<!-- # Unused Parameters # -->
@object: the object to search for the desired user-defined handler.
@signal_id: the number of the signal to search for.
@may_be_blocked: whether it is acceptable to return a blocked
handler.
-@Returns: the connection id, if a connection was found. 0 otherwise.
-<!-- # Unused Parameters # -->
-@i:
-@s:
-@b:
-<!-- ##### FUNCTION gtk_signal_handler_pending_by_func ##### -->
+<!-- ##### MACRO gtk_signal_handler_pending_by_func ##### -->
<para>
Returns a connection id corresponding to a given signal id, object, function
pointer and user data.
</para>
+@o:
+@s:
+@b:
+@f:
+@d:
+@Returns: the connection id, if a handler was found. 0 otherwise.
+<!-- # Unused Parameters # -->
@object: the object to search for the desired handler.
@signal_id: the number of the signal to search for.
@may_be_blocked: whether it is acceptable to return a blocked
handler.
@func: the function pointer to search for.
@data: the user data to search for.
-@Returns: the connection id, if a handler was found. 0 otherwise.
-<!-- # Unused Parameters # -->
-@o:
-@s:
-@b:
-@f:
-@d:
<!-- ##### MACRO gtk_signal_default_marshaller ##### -->
@draw_handle:
@draw_expander:
@draw_layout:
+@draw_resize_grip:
<!-- ##### FUNCTION gtk_style_new ##### -->
<para>
@textview: the object which received the signal.
+<!-- ##### SIGNAL GtkTextView::populate-popup ##### -->
+<para>
+
+</para>
+
+@textview: the object which received the signal.
+@arg1:
+
<!-- ##### SIGNAL GtkTextView::set-anchor ##### -->
<para>
@type_info: must not be null, and @type_info->type_name must also not be null.
-<!-- ##### FUNCTION gtk_type_name ##### -->
+<!-- ##### MACRO gtk_type_name ##### -->
<para>
</para>
-@type: a GtkType
@Returns: a pointer to the name of a type, or NULL if it has none.
+<!-- # Unused Parameters # -->
+@type: a GtkType
-<!-- ##### FUNCTION gtk_type_from_name ##### -->
+<!-- ##### MACRO gtk_type_from_name ##### -->
<para>
Get the internal representation of a type given its name.
</para>
-@name: the name of a gtk type
@Returns: a GtkType
+<!-- # Unused Parameters # -->
+@name: the name of a gtk type
-<!-- ##### FUNCTION gtk_type_parent ##### -->
+<!-- ##### MACRO gtk_type_parent ##### -->
<para>
</para>
-@type: a GtkType
@Returns: the GtkType of the parent
+<!-- # Unused Parameters # -->
+@type: a GtkType
<!-- ##### FUNCTION gtk_type_class ##### -->
@Returns: gpointer to a GtkTypeObject
-<!-- ##### FUNCTION gtk_type_is_a ##### -->
+<!-- ##### MACRO gtk_type_is_a ##### -->
<para>
Look in the type hierarchy to see if @type has @is_a_type among its
ancestors. Do so with a simple lookup, not a loop.
</para>
+@Returns:
+<!-- # Unused Parameters # -->
@type: GtkType
@is_a_type: GtkType
-@Returns:
<!-- ##### FUNCTION gtk_type_enum_get_values ##### -->
</para>
-@class:
+@klass:
@pspec:
+<!-- # Unused Parameters # -->
+@class:
<!-- ##### FUNCTION gtk_widget_class_install_style_property_parser ##### -->
</para>
-@class:
+@klass:
@pspec:
@parser:
+<!-- # Unused Parameters # -->
+@class:
<!-- ##### FUNCTION gtk_widget_region_intersect ##### -->
@widget: the object which received the signal.
@old_parent:
+<!-- ##### SIGNAL GtkWidget::popup-menu ##### -->
+<para>
+
+</para>
+
+@widget: the object which received the signal.
+
<!-- ##### SIGNAL GtkWidget::property-notify-event ##### -->
<para>
debug_updates = setting;
}
+/**
+ * gdk_window_constrain_size:
+ * @geometry: a #GdkGeometry structure
+ * @flags: a mask indicating what portions of @geometry are set
+ * @width: desired width of window
+ * @height: desired height of the window
+ * @new_width: location to store resulting width
+ * @new_height: location to store resulting height
+ *
+ * Constrains a desired width and height according to a
+ * set of geometry hints (such as minimum and maximum size).
+ */
+void
+gdk_window_constrain_size (GdkGeometry *geometry,
+ guint flags,
+ gint width,
+ gint height,
+ gint *new_width,
+ gint *new_height)
+{
+ /* This routine is partially borrowed from fvwm.
+ *
+ * Copyright 1993, Robert Nation
+ * You may use this code for any purpose, as long as the original
+ * copyright remains in the source code and all documentation
+ *
+ * which in turn borrows parts of the algorithm from uwm
+ */
+ gint min_width = 0;
+ gint min_height = 0;
+ gint base_width = 0;
+ gint base_height = 0;
+ gint xinc = 1;
+ gint yinc = 1;
+ gint max_width = G_MAXINT;
+ gint max_height = G_MAXINT;
+
+#define FLOOR(value, base) ( ((gint) ((value) / (base))) * (base) )
+
+ if ((flags & GDK_HINT_BASE_SIZE) && (flags & GDK_HINT_MIN_SIZE))
+ {
+ base_width = geometry->base_width;
+ base_height = geometry->base_height;
+ min_width = geometry->min_width;
+ min_height = geometry->min_height;
+ }
+ else if (flags & GDK_HINT_BASE_SIZE)
+ {
+ base_width = geometry->base_width;
+ base_height = geometry->base_height;
+ min_width = geometry->base_width;
+ min_height = geometry->base_height;
+ }
+ else if (flags & GDK_HINT_MIN_SIZE)
+ {
+ base_width = geometry->min_width;
+ base_height = geometry->min_height;
+ min_width = geometry->min_width;
+ min_height = geometry->min_height;
+ }
+
+ if (flags & GDK_HINT_MAX_SIZE)
+ {
+ max_width = geometry->max_width ;
+ max_height = geometry->max_height;
+ }
+
+ if (flags & GDK_HINT_RESIZE_INC)
+ {
+ xinc = MAX (xinc, geometry->width_inc);
+ yinc = MAX (yinc, geometry->height_inc);
+ }
+
+ /* clamp width and height to min and max values
+ */
+ width = CLAMP (width, min_width, max_width);
+ height = CLAMP (height, min_height, max_height);
+
+ /* shrink to base + N * inc
+ */
+ width = base_width + FLOOR (width - base_width, xinc);
+ height = base_height + FLOOR (height - base_height, yinc);
+
+ /* constrain aspect ratio, according to:
+ *
+ * width
+ * min_aspect <= -------- <= max_aspect
+ * height
+ */
+
+ if (flags & GDK_HINT_ASPECT &&
+ geometry->min_aspect > 0 &&
+ geometry->max_aspect > 0)
+ {
+ gint delta;
+
+ if (geometry->min_aspect * height > width)
+ {
+ delta = FLOOR (height - width * geometry->min_aspect, yinc);
+ if (height - delta >= min_height)
+ height -= delta;
+ else
+ {
+ delta = FLOOR (height * geometry->min_aspect - width, xinc);
+ if (width + delta <= max_width)
+ width += delta;
+ }
+ }
+
+ if (geometry->max_aspect * height < width)
+ {
+ delta = FLOOR (width - height * geometry->max_aspect, xinc);
+ if (width - delta >= min_width)
+ width -= delta;
+ else
+ {
+ delta = FLOOR (width / geometry->max_aspect - height, yinc);
+ if (height + delta <= max_height)
+ height += delta;
+ }
+ }
+ }
+
+#undef FLOOR
+
+ *new_width = width;
+ *new_height = height;
+}
GDK_GRAVITY_STATIC
} GdkGravity;
+
+typedef enum
+{
+ GDK_WINDOW_EDGE_NORTH_WEST,
+ GDK_WINDOW_EDGE_NORTH,
+ GDK_WINDOW_EDGE_NORTH_EAST,
+ GDK_WINDOW_EDGE_WEST,
+ GDK_WINDOW_EDGE_EAST,
+ GDK_WINDOW_EDGE_SOUTH_WEST,
+ GDK_WINDOW_EDGE_SOUTH,
+ GDK_WINDOW_EDGE_SOUTH_EAST
+} GdkWindowEdge;
+
struct _GdkWindowAttr
{
gchar *title;
void gdk_window_register_dnd (GdkWindow *window);
+void gdk_window_begin_resize_drag (GdkWindow *window,
+ GdkWindowEdge edge,
+ gint button,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp);
+void gdk_window_begin_move_drag (GdkWindow *window,
+ gint button,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp);
+
/* Interface for dirty-region queueing */
void gdk_window_invalidate_rect (GdkWindow *window,
GdkRectangle *rect,
/* Enable/disable flicker, so you can tell if your code is inefficient. */
void gdk_window_set_debug_updates (gboolean setting);
+void gdk_window_constrain_size (GdkGeometry *geometry,
+ guint flags,
+ gint width,
+ gint height,
+ gint *new_width,
+ gint *new_height);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
if (window != NULL)
gdk_window_ref (window);
+ if (_gdk_moveresize_window &&
+ (xevent->xany.type == MotionNotify ||
+ xevent->xany.type == ButtonRelease))
+ {
+ _gdk_moveresize_handle_event (xevent);
+ gdk_window_unref (window);
+ return FALSE;
+ }
+
if (wmspec_check_window != None &&
xevent->xany.window == wmspec_check_window)
{
window_private->y = event->configure.y;
GDK_WINDOW_IMPL_X11 (window_private->impl)->width = xevent->xconfigure.width;
GDK_WINDOW_IMPL_X11 (window_private->impl)->height = xevent->xconfigure.height;
- if (window_private->resize_count > 1)
- window_private->resize_count -= 1;
+ if (window_private->resize_count >= 1)
+ {
+ window_private->resize_count -= 1;
+
+ if (window_private->resize_count == 0 &&
+ window == _gdk_moveresize_window)
+ _gdk_moveresize_configure_done ();
+ }
}
break;
XRectangle **rects,
gint *n_rects);
+void _gdk_moveresize_handle_event (XEvent *event);
+void _gdk_moveresize_configure_done (void);
+
extern GdkDrawableClass _gdk_x11_drawable_class;
extern gboolean gdk_use_xshm;
extern Atom gdk_wm_delete_window;
*/
extern gboolean _gdk_have_xkb_autorepeat;
+extern GdkWindow *_gdk_moveresize_window;
+
#endif /* __GDK_PRIVATE_X11_H__ */
width, height);
else
{
+ GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
+
+ if (width != impl->width || height != impl->height)
+ private->resize_count += 1;
+
XResizeWindow (GDK_WINDOW_XDISPLAY (window),
GDK_WINDOW_XID (window),
width, height);
- private->resize_count += 1;
}
}
}
_gdk_window_move_resize_child (window, x, y, width, height);
else
{
+ GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
+
+ if (width != impl->width || height != impl->height)
+ private->resize_count += 1;
+
XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window),
GDK_WINDOW_XID (window),
x, y, width, height);
- private->resize_count += 1;
}
}
}
if (geom_mask & GDK_HINT_WIN_GRAVITY)
{
size_hints.flags |= PWinGravity;
- size_hints.width_inc = geometry->win_gravity;
+ size_hints.win_gravity = geometry->win_gravity;
}
/* FIXME: Would it be better to delete this property of
&size_hints);
}
+static void
+gdk_window_get_geometry_hints (GdkWindow *window,
+ GdkGeometry *geometry,
+ GdkWindowHints *geom_mask)
+{
+ XSizeHints size_hints;
+ glong junk_size_mask = 0;
+
+ g_return_if_fail (GDK_IS_WINDOW (window));
+ g_return_if_fail (geometry != NULL);
+ g_return_if_fail (geom_mask != NULL);
+
+ *geom_mask = 0;
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ if (!XGetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ &size_hints,
+ &junk_size_mask))
+ return;
+
+ if (size_hints.flags & PMinSize)
+ {
+ *geom_mask |= GDK_HINT_MIN_SIZE;
+ geometry->min_width = size_hints.min_width;
+ geometry->min_height = size_hints.min_height;
+ }
+
+ if (size_hints.flags & PMaxSize)
+ {
+ *geom_mask |= GDK_HINT_MAX_SIZE;
+ geometry->max_width = MAX (size_hints.max_width, 1);
+ geometry->max_height = MAX (size_hints.max_height, 1);
+ }
+
+ if (size_hints.flags & PResizeInc)
+ {
+ *geom_mask |= GDK_HINT_RESIZE_INC;
+ geometry->width_inc = size_hints.width_inc;
+ geometry->height_inc = size_hints.height_inc;
+ }
+
+ if (size_hints.flags & PAspect)
+ {
+ *geom_mask |= GDK_HINT_ASPECT;
+
+ geometry->min_aspect = (gdouble) size_hints.min_aspect.x / (gdouble) size_hints.min_aspect.y;
+ geometry->max_aspect = (gdouble) size_hints.max_aspect.x / (gdouble) size_hints.max_aspect.y;
+ }
+
+ if (size_hints.flags & PWinGravity)
+ {
+ *geom_mask |= GDK_HINT_WIN_GRAVITY;
+ geometry->win_gravity = size_hints.win_gravity;
+ }
+}
+
static gboolean
utf8_is_latin1 (const gchar *str)
{
return root;
}
+static void
+wmspec_moveresize (GdkWindow *window,
+ gint direction,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp)
+{
+ XEvent xev;
+
+ /* Release passive grab */
+ gdk_pointer_ungrab (timestamp);
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.display = gdk_display;
+ xev.xclient.window = GDK_WINDOW_XID (window);
+ xev.xclient.message_type = gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE);
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = root_x;
+ xev.xclient.data.l[1] = root_y;
+ xev.xclient.data.l[2] = direction;
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent (gdk_display, gdk_root_window, False,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+}
+
+/* From the WM spec */
+#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
+#define _NET_WM_MOVERESIZE_SIZE_TOP 1
+#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
+#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
+#define _NET_WM_MOVERESIZE_SIZE_LEFT 7
+#define _NET_WM_MOVERESIZE_MOVE 8
+
+static void
+wmspec_resize_drag (GdkWindow *window,
+ GdkWindowEdge edge,
+ gint button,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp)
+{
+ gint direction;
+
+ /* Let the compiler turn a switch into a table, instead
+ * of doing the table manually, this way is easier to verify.
+ */
+ switch (edge)
+ {
+ case GDK_WINDOW_EDGE_NORTH_WEST:
+ direction = _NET_WM_MOVERESIZE_SIZE_TOPLEFT;
+ break;
+
+ case GDK_WINDOW_EDGE_NORTH:
+ direction = _NET_WM_MOVERESIZE_SIZE_TOP;
+ break;
+
+ case GDK_WINDOW_EDGE_NORTH_EAST:
+ direction = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT;
+ break;
+
+ case GDK_WINDOW_EDGE_WEST:
+ direction = _NET_WM_MOVERESIZE_SIZE_LEFT;
+ break;
+
+ case GDK_WINDOW_EDGE_EAST:
+ direction = _NET_WM_MOVERESIZE_SIZE_RIGHT;
+ break;
+
+ case GDK_WINDOW_EDGE_SOUTH_WEST:
+ direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT;
+ break;
+
+ case GDK_WINDOW_EDGE_SOUTH:
+ direction = _NET_WM_MOVERESIZE_SIZE_BOTTOM;
+ break;
+
+ case GDK_WINDOW_EDGE_SOUTH_EAST:
+ direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT;
+ break;
+
+ default:
+ g_warning ("gdk_window_begin_resize_drag: bad resize edge %d!",
+ edge);
+ return;
+ break;
+ }
+
+ wmspec_moveresize (window, direction, root_x, root_y, timestamp);
+}
+
+/* This is global for use in gdkevents-x11.c */
+GdkWindow *_gdk_moveresize_window;
+
+static GdkWindow *moveresize_emulation_window = NULL;
+static gboolean is_resize = FALSE;
+static GdkWindowEdge resize_edge;
+static gint moveresize_button;
+static gint moveresize_x;
+static gint moveresize_y;
+static gint moveresize_orig_x;
+static gint moveresize_orig_y;
+static gint moveresize_orig_width;
+static gint moveresize_orig_height;
+static GdkWindowHints moveresize_geom_mask = 0;
+static GdkGeometry moveresize_geometry;
+static Time moveresize_process_time;
+
+static XEvent *moveresize_pending_event;
+
+static void
+update_pos (gint new_root_x,
+ gint new_root_y)
+{
+ gint dx, dy;
+
+ dx = new_root_x - moveresize_x;
+ dy = new_root_y - moveresize_y;
+
+ if (is_resize)
+ {
+ gint w, h;
+
+ w = moveresize_orig_width;
+ h = moveresize_orig_height;
+
+ switch (resize_edge)
+ {
+ case GDK_WINDOW_EDGE_SOUTH_EAST:
+ w += dx;
+ h += dy;
+ break;
+
+ }
+
+ w = MAX (w, 1);
+ h = MAX (h, 1);
+
+ if (moveresize_geom_mask)
+ {
+ gdk_window_constrain_size (&moveresize_geometry,
+ moveresize_geom_mask,
+ w, h,
+ &w, &h);
+ }
+
+ gdk_window_resize (_gdk_moveresize_window, w, h);
+ }
+ else
+ {
+ gint x, y;
+
+ x = moveresize_orig_x + dx;
+ y = moveresize_orig_y + dy;
+
+ gdk_window_move (_gdk_moveresize_window, x, y);
+ }
+}
+
+static void
+finish_drag (void)
+{
+ gdk_window_destroy (moveresize_emulation_window);
+ moveresize_emulation_window = NULL;
+ _gdk_moveresize_window = NULL;
+
+ if (moveresize_pending_event)
+ {
+ g_free (moveresize_pending_event);
+ moveresize_pending_event = NULL;
+ }
+}
+
+static int
+lookahead_motion_predicate (Display *display,
+ XEvent *event,
+ XPointer arg)
+{
+ gboolean *seen_release = (gboolean *)arg;
+
+ if (*seen_release)
+ return False;
+
+ switch (event->xany.type)
+ {
+ case ButtonRelease:
+ *seen_release = TRUE;
+ break;
+ case MotionNotify:
+ moveresize_process_time = event->xmotion.time;
+ break;
+ default:
+ break;
+ }
+
+ return False;
+}
+
+static gboolean
+moveresize_lookahead (XEvent *event)
+{
+ XEvent tmp_event;
+ gboolean seen_release = FALSE;
+
+ if (moveresize_process_time)
+ {
+ if (event->xmotion.time == moveresize_process_time)
+ {
+ moveresize_process_time = 0;
+ return TRUE;
+ }
+ else
+ return FALSE;
+ }
+
+ XCheckIfEvent (gdk_display, &tmp_event,
+ lookahead_motion_predicate, (XPointer)&seen_release);
+
+ return moveresize_process_time == 0;
+}
+
+void
+_gdk_moveresize_handle_event (XEvent *event)
+{
+ guint button_mask = 0;
+ GdkWindowObject *window_private = (GdkWindowObject *) _gdk_moveresize_window;
+
+ button_mask = GDK_BUTTON1_MASK << (moveresize_button - 1);
+
+ switch (event->xany.type)
+ {
+ case MotionNotify:
+ if (window_private->resize_count > 0)
+ {
+ if (moveresize_pending_event)
+ *moveresize_pending_event = *event;
+ else
+ moveresize_pending_event = g_memdup (event, sizeof (XEvent));
+
+ break;
+ }
+ if (!moveresize_lookahead (event))
+ break;
+
+ update_pos (event->xmotion.x_root,
+ event->xmotion.y_root);
+
+ /* This should never be triggered in normal cases, but in the
+ * case where the drag started without an implicit grab being
+ * in effect, we could miss the release if it occurs before
+ * we grab the pointer; this ensures that we will never
+ * get a permanently stuck grab.
+ */
+ if ((event->xmotion.state & button_mask) == 0)
+ finish_drag ();
+ break;
+
+ case ButtonRelease:
+ update_pos (event->xbutton.x_root,
+ event->xbutton.y_root);
+
+ if (event->xbutton.button == moveresize_button)
+ finish_drag ();
+ break;
+ }
+}
+
+void
+_gdk_moveresize_configure_done (void)
+{
+ XEvent *tmp_event;
+
+ if (moveresize_pending_event)
+ {
+ tmp_event = moveresize_pending_event;
+ moveresize_pending_event = NULL;
+ _gdk_moveresize_handle_event (tmp_event);
+ g_free (tmp_event);
+ }
+}
+
+static void
+create_moveresize_window (guint32 timestamp)
+{
+ GdkWindowAttr attributes;
+ gint attributes_mask;
+ GdkGrabStatus status;
+
+ g_assert (moveresize_emulation_window == NULL);
+
+ attributes.x = -100;
+ attributes.y = -100;
+ attributes.width = 10;
+ attributes.height = 10;
+ attributes.window_type = GDK_WINDOW_TEMP;
+ attributes.wclass = GDK_INPUT_ONLY;
+ attributes.override_redirect = TRUE;
+ attributes.event_mask = 0;
+
+ attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_NOREDIR;
+
+ moveresize_emulation_window =
+ gdk_window_new (NULL, &attributes, attributes_mask);
+
+ gdk_window_show (moveresize_emulation_window);
+
+ status = gdk_pointer_grab (moveresize_emulation_window,
+ FALSE,
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_MASK,
+ FALSE,
+ NULL,
+ timestamp);
+
+ if (status != GDK_GRAB_SUCCESS)
+ {
+ /* If this fails, some other client has grabbed the window
+ * already.
+ */
+ gdk_window_destroy (moveresize_emulation_window);
+ moveresize_emulation_window = NULL;
+ }
+
+ moveresize_process_time = 0;
+}
+
+static void
+emulate_resize_drag (GdkWindow *window,
+ GdkWindowEdge edge,
+ gint button,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp)
+{
+ is_resize = TRUE;
+ moveresize_button = button;
+ resize_edge = edge;
+ moveresize_x = root_x;
+ moveresize_y = root_y;
+ _gdk_moveresize_window = GDK_WINDOW (g_object_ref (G_OBJECT (window)));
+
+ gdk_window_get_size (window, &moveresize_orig_width, &moveresize_orig_height);
+
+ moveresize_geom_mask = 0;
+ gdk_window_get_geometry_hints (window,
+ &moveresize_geometry,
+ &moveresize_geom_mask);
+
+ create_moveresize_window (timestamp);
+}
+
+static void
+emulate_move_drag (GdkWindow *window,
+ gint button,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp)
+{
+ is_resize = FALSE;
+ moveresize_button = button;
+ moveresize_x = root_x;
+ moveresize_y = root_y;
+ _gdk_moveresize_window = GDK_WINDOW (g_object_ref (G_OBJECT (window)));
+
+ gdk_window_get_deskrelative_origin (_gdk_moveresize_window,
+ &moveresize_orig_x,
+ &moveresize_orig_y);
+
+ create_moveresize_window (timestamp);
+}
+
+void
+gdk_window_begin_resize_drag (GdkWindow *window,
+ GdkWindowEdge edge,
+ gint button,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+ g_return_if_fail (moveresize_emulation_window == NULL);
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ if (gdk_net_wm_supports (gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE)))
+ wmspec_resize_drag (window, edge, button, root_x, root_y, timestamp);
+ else
+ emulate_resize_drag (window, edge, button, root_x, root_y, timestamp);
+}
+
+void
+gdk_window_begin_move_drag (GdkWindow *window,
+ gint button,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+ g_return_if_fail (moveresize_emulation_window == NULL);
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ if (gdk_net_wm_supports (gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE)))
+ wmspec_moveresize (window, _NET_WM_MOVERESIZE_MOVE,
+ root_x, root_y, timestamp);
+ else
+ emulate_move_drag (window, button, root_x, root_y, timestamp);
+}
+
#include "gtklabel.h"
#include "gtksignal.h"
#include "gtkstatusbar.h"
+#include "gtkwindow.h"
typedef struct _GtkStatusbarMsg GtkStatusbarMsg;
SIGNAL_LAST
};
-static void gtk_statusbar_class_init (GtkStatusbarClass *class);
-static void gtk_statusbar_init (GtkStatusbar *statusbar);
-static void gtk_statusbar_destroy (GtkObject *object);
-static void gtk_statusbar_update (GtkStatusbar *statusbar,
- guint context_id,
- const gchar *text);
-
+static void gtk_statusbar_class_init (GtkStatusbarClass *class);
+static void gtk_statusbar_init (GtkStatusbar *statusbar);
+static void gtk_statusbar_destroy (GtkObject *object);
+static void gtk_statusbar_update (GtkStatusbar *statusbar,
+ guint context_id,
+ const gchar *text);
+static void gtk_statusbar_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+static void gtk_statusbar_realize (GtkWidget *widget);
+static void gtk_statusbar_unrealize (GtkWidget *widget);
+static void gtk_statusbar_map (GtkWidget *widget);
+static void gtk_statusbar_unmap (GtkWidget *widget);
+static gboolean gtk_statusbar_button_press (GtkWidget *widget,
+ GdkEventButton *event);
+static gboolean gtk_statusbar_expose_event (GtkWidget *widget,
+ GdkEventExpose *event);
+static void gtk_statusbar_create_window (GtkStatusbar *statusbar);
+static void gtk_statusbar_destroy_window (GtkStatusbar *statusbar);
+
static GtkContainerClass *parent_class;
static guint statusbar_signals[SIGNAL_LAST] = { 0 };
object_class->destroy = gtk_statusbar_destroy;
+ widget_class->size_allocate = gtk_statusbar_size_allocate;
+
+ widget_class->realize = gtk_statusbar_realize;
+ widget_class->unrealize = gtk_statusbar_unrealize;
+ widget_class->map = gtk_statusbar_map;
+ widget_class->unmap = gtk_statusbar_unmap;
+
+ widget_class->button_press_event = gtk_statusbar_button_press;
+ widget_class->expose_event = gtk_statusbar_expose_event;
+
class->messages_mem_chunk = g_mem_chunk_new ("GtkStatusBar messages mem chunk",
sizeof (GtkStatusbarMsg),
sizeof (GtkStatusbarMsg) * 64,
class->text_pushed = gtk_statusbar_update;
class->text_popped = gtk_statusbar_update;
-
+
statusbar_signals[SIGNAL_TEXT_PUSHED] =
gtk_signal_new ("text_pushed",
GTK_RUN_LAST,
box->spacing = 2;
box->homogeneous = FALSE;
+ statusbar->has_resize_grip = TRUE;
+
statusbar->frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (statusbar->frame), GTK_SHADOW_IN);
gtk_box_pack_start (box, statusbar->frame, TRUE, TRUE, 0);
}
}
+void
+gtk_statusbar_set_has_resize_grip (GtkStatusbar *statusbar,
+ gboolean setting)
+{
+ g_return_if_fail (GTK_IS_STATUSBAR (statusbar));
+
+ setting = setting != FALSE;
+
+ if (setting != statusbar->has_resize_grip)
+ {
+ statusbar->has_resize_grip = setting;
+ gtk_widget_queue_draw (GTK_WIDGET (statusbar));
+
+ if (GTK_WIDGET_REALIZED (statusbar))
+ {
+ if (statusbar->has_resize_grip && statusbar->grip_window == NULL)
+ gtk_statusbar_create_window (statusbar);
+ else if (!statusbar->has_resize_grip && statusbar->grip_window != NULL)
+ gtk_statusbar_destroy_window (statusbar);
+ }
+ }
+}
+
+gboolean
+gtk_statusbar_get_has_resize_grip (GtkStatusbar *statusbar)
+{
+ g_return_val_if_fail (GTK_IS_STATUSBAR (statusbar), FALSE);
+
+ return statusbar->has_resize_grip;
+}
+
static void
gtk_statusbar_destroy (GtkObject *object)
{
GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
+
+static void
+get_grip_rect (GtkStatusbar *statusbar,
+ GdkRectangle *rect)
+{
+ GtkWidget *widget;
+ gint w, h;
+
+ widget = GTK_WIDGET (statusbar);
+
+ /* These are in effect the max/default size of the grip. */
+ w = 18;
+ h = 18;
+
+ if (w > (widget->allocation.width))
+ w = widget->allocation.width;
+
+ if (h > (widget->allocation.height - widget->style->ythickness))
+ h = widget->allocation.height - widget->style->ythickness;
+
+ rect->x = widget->allocation.x + widget->allocation.width - w;
+ rect->y = widget->allocation.y + widget->allocation.height - h;
+ rect->width = w;
+ rect->height = h;
+}
+
+static void
+gtk_statusbar_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ GtkStatusbar *statusbar;
+ GdkRectangle rect;
+
+ statusbar = GTK_STATUSBAR (widget);
+
+ GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation);
+
+ get_grip_rect (statusbar, &rect);
+
+ if (statusbar->grip_window)
+ gdk_window_move_resize (statusbar->grip_window,
+ rect.x, rect.y,
+ rect.width, rect.height);
+}
+
+static void
+gtk_statusbar_create_window (GtkStatusbar *statusbar)
+{
+ GtkWidget *widget;
+ GdkWindowAttr attributes;
+ gint attributes_mask;
+ GdkRectangle rect;
+
+ g_return_if_fail (GTK_WIDGET_REALIZED (statusbar));
+ g_return_if_fail (statusbar->has_resize_grip);
+
+ widget = GTK_WIDGET (statusbar);
+
+ get_grip_rect (statusbar, &rect);
+
+ attributes.x = rect.x;
+ attributes.y = rect.y;
+ attributes.width = rect.width;
+ attributes.height = rect.height;
+ attributes.window_type = GDK_WINDOW_CHILD;
+ attributes.wclass = GDK_INPUT_ONLY;
+ attributes.event_mask = gtk_widget_get_events (widget) |
+ GDK_BUTTON_PRESS_MASK;
+
+ attributes_mask = GDK_WA_X | GDK_WA_Y;
+
+ statusbar->grip_window = gdk_window_new (widget->window,
+ &attributes, attributes_mask);
+ gdk_window_set_user_data (statusbar->grip_window, widget);
+}
+
+static void
+gtk_statusbar_destroy_window (GtkStatusbar *statusbar)
+{
+ gdk_window_set_user_data (statusbar->grip_window, NULL);
+ gdk_window_destroy (statusbar->grip_window);
+ statusbar->grip_window = NULL;
+}
+
+static void
+gtk_statusbar_realize (GtkWidget *widget)
+{
+ GtkStatusbar *statusbar;
+
+ statusbar = GTK_STATUSBAR (widget);
+
+ (* GTK_WIDGET_CLASS (parent_class)->realize) (widget);
+
+ if (statusbar->has_resize_grip)
+ gtk_statusbar_create_window (statusbar);
+}
+
+static void
+gtk_statusbar_unrealize (GtkWidget *widget)
+{
+ GtkStatusbar *statusbar;
+
+ statusbar = GTK_STATUSBAR (widget);
+
+ if (statusbar->grip_window)
+ gtk_statusbar_destroy_window (statusbar);
+
+ (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
+}
+
+static void
+gtk_statusbar_map (GtkWidget *widget)
+{
+ GtkStatusbar *statusbar;
+
+ statusbar = GTK_STATUSBAR (widget);
+
+ (* GTK_WIDGET_CLASS (parent_class)->map) (widget);
+
+ if (statusbar->grip_window)
+ gdk_window_show (statusbar->grip_window);
+}
+
+static void
+gtk_statusbar_unmap (GtkWidget *widget)
+{
+ GtkStatusbar *statusbar;
+
+ statusbar = GTK_STATUSBAR (widget);
+
+ if (statusbar->grip_window)
+ gdk_window_hide (statusbar->grip_window);
+
+ (* GTK_WIDGET_CLASS (parent_class)->unmap) (widget);
+}
+
+static gboolean
+gtk_statusbar_button_press (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ GtkStatusbar *statusbar;
+ GtkWidget *ancestor;
+
+ statusbar = GTK_STATUSBAR (widget);
+
+ if (!statusbar->has_resize_grip)
+ return FALSE;
+
+ ancestor = gtk_widget_get_toplevel (widget);
+
+ if (!GTK_IS_WINDOW (ancestor))
+ return FALSE;
+
+ if (event->button == 1)
+ gtk_window_begin_resize_drag (GTK_WINDOW (ancestor),
+ GDK_WINDOW_EDGE_SOUTH_EAST,
+ event->button,
+ event->x_root, event->y_root,
+ event->time);
+ else if (event->button == 2)
+ gtk_window_begin_move_drag (GTK_WINDOW (ancestor),
+ event->button,
+ event->x_root, event->y_root,
+ event->time);
+ else
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+gtk_statusbar_expose_event (GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ GtkStatusbar *statusbar;
+ GdkRectangle rect;
+
+ statusbar = GTK_STATUSBAR (widget);
+
+ GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
+
+ if (statusbar->has_resize_grip)
+ {
+ get_grip_rect (statusbar, &rect);
+
+ gtk_paint_resize_grip (widget->style,
+ widget->window,
+ GTK_WIDGET_STATE (widget),
+ NULL,
+ widget,
+ "statusbar",
+ GDK_WINDOW_EDGE_SOUTH_EAST,
+ rect.x, rect.y,
+ /* don't draw grip over the frame, though you
+ * can click on the frame.
+ */
+ rect.width - widget->style->xthickness,
+ rect.height - widget->style->ythickness);
+ }
+
+ return FALSE;
+}
guint seq_context_id;
guint seq_message_id;
+
+ GdkWindow *grip_window;
+
+ guint has_resize_grip : 1;
};
struct _GtkStatusbarClass
guint context_id,
guint message_id);
-
+void gtk_statusbar_set_has_resize_grip (GtkStatusbar *statusbar,
+ gboolean setting);
+gboolean gtk_statusbar_get_has_resize_grip (GtkStatusbar *statusbar);
#ifdef __cplusplus
}
gint x,
gint y,
PangoLayout *layout);
+static void gtk_default_draw_resize_grip (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ const gchar *detail,
+ GdkWindowEdge edge,
+ gint x,
+ gint y,
+ gint width,
+ gint height);
+
static void gtk_style_shade (GdkColor *a,
GdkColor *b,
gdouble k);
klass->draw_handle = gtk_default_draw_handle;
klass->draw_expander = gtk_default_draw_expander;
klass->draw_layout = gtk_default_draw_layout;
+ klass->draw_resize_grip = gtk_default_draw_resize_grip;
}
static void
x, y, layout);
}
+void
+gtk_draw_resize_grip (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GdkWindowEdge edge,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ g_return_if_fail (GTK_IS_STYLE (style));
+ g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
+
+ GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
+ NULL, NULL, NULL,
+ edge,
+ x, y, width, height);
+}
+
+
void
gtk_style_set_background (GtkStyle *style,
GdkWindow *window,
gdk_gc_set_clip_rectangle (style->fg_gc[state_type], NULL);
}
+static void
+gtk_default_draw_resize_grip (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ const gchar *detail,
+ GdkWindowEdge edge,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ g_return_if_fail (GTK_IS_STYLE (style));
+ g_return_if_fail (window != NULL);
+
+ if (area)
+ {
+ gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
+ gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
+ }
+
+ /* make it square */
+ if (width != height)
+ width = height = MIN (width, height);
+
+ switch (edge)
+ {
+ case GDK_WINDOW_EDGE_SOUTH_EAST:
+ {
+ gint xi, yi;
+
+ xi = x;
+ yi = y;
+
+ while (xi < (x + width - 3))
+ {
+ gdk_draw_line (window,
+ style->light_gc[state_type],
+ xi, y + height,
+ x + width, yi);
+
+ ++xi;
+ ++yi;
+
+ gdk_draw_line (window,
+ style->dark_gc[state_type],
+ xi, y + height,
+ x + width, yi);
+
+ ++xi;
+ ++yi;
+
+ gdk_draw_line (window,
+ style->dark_gc[state_type],
+ xi, y + height,
+ x + width, yi);
+
+ xi += 3;
+ yi += 3;
+ }
+ }
+ break;
+
+ }
+
+ if (area)
+ {
+ gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
+ gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
+ }
+}
+
static void
gtk_style_shade (GdkColor *a,
GdkColor *b,
widget, detail, x, y, layout);
}
+void
+gtk_paint_resize_grip (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ const gchar *detail,
+ GdkWindowEdge edge,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+
+{
+ g_return_if_fail (GTK_IS_STYLE (style));
+ g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
+
+ GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
+ area, widget, detail,
+ edge, x, y, width, height);
+}
gint x,
gint y,
PangoLayout *layout);
+ void (*draw_resize_grip) (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ const gchar *detail,
+ GdkWindowEdge edge,
+ gint x,
+ gint y,
+ gint width,
+ gint height);
};
gint y,
PangoLayout *layout);
+void gtk_draw_resize_grip (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GdkWindowEdge edge,
+ gint x,
+ gint y,
+ gint width,
+ gint height);
+
void gtk_paint_hline (GtkStyle *style,
GdkWindow *window,
GtkStateType state_type,
gint y,
PangoLayout *layout);
+void gtk_paint_resize_grip (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ const gchar *detail,
+ GdkWindowEdge edge,
+ gint x,
+ gint y,
+ gint width,
+ gint height);
+
/* --- private API --- */
const GValue* _gtk_style_peek_property_value (GtkStyle *style,
}
}
-
-/* Constrain a window size to obey the hints passed in geometry
- * and flags. The result will be stored in *new_width and *new_height
- *
- * This routine is partially borrowed from fvwm.
- *
- * Copyright 1993, Robert Nation
- * You may use this code for any purpose, as long as the original
- * copyright remains in the source code and all documentation
- *
- * which in turn borrows parts of the algorithm from uwm
- */
static void
gtk_window_constrain_size (GtkWindow *window,
GdkGeometry *geometry,
gint *new_width,
gint *new_height)
{
- gint min_width = 0;
- gint min_height = 0;
- gint base_width = 0;
- gint base_height = 0;
- gint xinc = 1;
- gint yinc = 1;
- gint max_width = G_MAXINT;
- gint max_height = G_MAXINT;
-
-#define FLOOR(value, base) ( ((gint) ((value) / (base))) * (base) )
-
- if ((flags & GDK_HINT_BASE_SIZE) && (flags & GDK_HINT_MIN_SIZE))
- {
- base_width = geometry->base_width;
- base_height = geometry->base_height;
- min_width = geometry->min_width;
- min_height = geometry->min_height;
- }
- else if (flags & GDK_HINT_BASE_SIZE)
- {
- base_width = geometry->base_width;
- base_height = geometry->base_height;
- min_width = geometry->base_width;
- min_height = geometry->base_height;
- }
- else if (flags & GDK_HINT_MIN_SIZE)
- {
- base_width = geometry->min_width;
- base_height = geometry->min_height;
- min_width = geometry->min_width;
- min_height = geometry->min_height;
- }
-
- if (flags & GDK_HINT_MAX_SIZE)
- {
- max_width = geometry->max_width ;
- max_height = geometry->max_height;
- }
-
- if (flags & GDK_HINT_RESIZE_INC)
- {
- xinc = MAX (xinc, geometry->width_inc);
- yinc = MAX (yinc, geometry->height_inc);
- }
-
- /* clamp width and height to min and max values
- */
- width = CLAMP (width, min_width, max_width);
- height = CLAMP (height, min_height, max_height);
-
- /* shrink to base + N * inc
- */
- width = base_width + FLOOR (width - base_width, xinc);
- height = base_height + FLOOR (height - base_height, yinc);
-
- /* constrain aspect ratio, according to:
- *
- * width
- * min_aspect <= -------- <= max_aspect
- * height
- */
-
- if (flags & GDK_HINT_ASPECT &&
- geometry->min_aspect > 0 &&
- geometry->max_aspect > 0)
- {
- gint delta;
-
- if (geometry->min_aspect * height > width)
- {
- delta = FLOOR (height - width * geometry->min_aspect, yinc);
- if (height - delta >= min_height)
- height -= delta;
- else
- {
- delta = FLOOR (height * geometry->min_aspect - width, xinc);
- if (width + delta <= max_width)
- width += delta;
- }
- }
-
- if (geometry->max_aspect * height < width)
- {
- delta = FLOOR (width - height * geometry->max_aspect, xinc);
- if (width - delta >= min_width)
- width -= delta;
- else
- {
- delta = FLOOR (width / geometry->max_aspect - height, yinc);
- if (height + delta <= max_height)
- height += delta;
- }
- }
- }
-
-#undef FLOOR
-
- *new_width = width;
- *new_height = height;
+ gdk_window_constrain_size (geometry, flags, width, height,
+ new_width, new_height);
}
/* Compute the set of geometry hints and flags for a window
gdk_window_unmaximize (toplevel);
}
+/**
+ * gtk_window_begin_resize_drag:
+ * @window: a #GtkWindow
+ * @button: mouse button that initiated the drag
+ * @edge: position of the resize control
+ * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
+ * @root_y: Y position where the user clicked to initiate the drag
+ * @timestamp: timestamp from the click event that initiated the drag
+ *
+ * Starts resizing a window. This function is used if an application
+ * has window resizing controls. When GDK can support it, the resize
+ * will be done using the standard mechanism for the window manager or
+ * windowing system. Otherwise, GDK will try to emulate window
+ * resizing, potentially not all that well, depending on the windowing system.
+ *
+ **/
+void
+gtk_window_begin_resize_drag (GtkWindow *window,
+ GdkWindowEdge edge,
+ gint button,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp)
+{
+ GtkWidget *widget;
+ GdkWindow *toplevel;
+
+ g_return_if_fail (GTK_IS_WINDOW (window));
+ g_return_if_fail (GTK_WIDGET_VISIBLE (window));
+
+ widget = GTK_WIDGET (window);
+
+ if (window->frame)
+ toplevel = window->frame;
+ else
+ toplevel = widget->window;
+
+ gdk_window_begin_resize_drag (toplevel,
+ edge, button,
+ root_x, root_y,
+ timestamp);
+}
-
-
-
+/**
+ * gtk_window_begin_move_drag:
+ * @button: mouse button that initiated the drag
+ * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
+ * @root_y: Y position where the user clicked to initiate the drag
+ * @timestamp: timestamp from the click event that initiated the drag
+ *
+ * Starts moving a window. This function is used if an application
+ * has window movement grips. When GDK can support it, the window movement
+ * will be done using the standard mechanism for the window manager or
+ * windowing system. Otherwise, GDK will try to emulate window
+ * movement, potentially not all that well, depending on the windowing system.
+ *
+ **/
+void
+gtk_window_begin_move_drag (GtkWindow *window,
+ gint button,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp)
+{
+ GtkWidget *widget;
+ GdkWindow *toplevel;
+
+ g_return_if_fail (GTK_IS_WINDOW (window));
+ g_return_if_fail (GTK_WIDGET_VISIBLE (window));
+
+ widget = GTK_WIDGET (window);
+
+ if (window->frame)
+ toplevel = window->frame;
+ else
+ toplevel = widget->window;
+
+ gdk_window_begin_move_drag (toplevel,
+ button,
+ root_x, root_y,
+ timestamp);
+}
/* If window is set modal, input will be grabbed when show and released when hide */
void gtk_window_set_modal (GtkWindow *window,
gboolean modal);
-GList* gtk_window_list_toplevels (void);
+GList* gtk_window_list_toplevels (void);
void gtk_window_add_mnemonic (GtkWindow *window,
guint keyval,
void gtk_window_maximize (GtkWindow *window);
void gtk_window_unmaximize (GtkWindow *window);
+void gtk_window_begin_resize_drag (GtkWindow *window,
+ GdkWindowEdge edge,
+ gint button,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp);
+void gtk_window_begin_move_drag (GtkWindow *window,
+ gint button,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp);
+
/* --- internal functions --- */
void gtk_window_set_focus (GtkWindow *window,